
var AUDIOBACK = document.createElement('audio');
var AUDIOSOURCEBACK = document.createElement('source');

/**
 * MENU
 **/
var MenuJ1 = function(){

	this.J = '';

	//Initialisation
	this.init = function(j){
		this.J = j;
	};
	//Mise à jour
	this.update = function(){
		this.render();
	}

	//Affichage
	this.render = function(){
		ctx[this.J].fillStyle = "#88F";
		ctx[this.J].fillRect(0, 0, MAX_WIDTH_J1, MAX_HEIGHT_J1);
		ctx[this.J].fillStyle = "#000";		
		var header = '[PRESS ENTER TO START]';
		ctx[this.J].fillText(header, (MAX_WIDTH_J1/2)-header.length*3, MAX_HEIGHT_J1/2);
	};
	//Gestion des inputs
	this.input = function(){
		
		if(getKey('enter').state){
			AUDIOSOURCEBACK.src = 'audio/music_loop.wav';
			AUDIOSOURCEBACK.type = 'audio/wav';
			AUDIOBACK.controls = 'controls';
			AUDIOBACK.autoplay = 'autoplay';
			AUDIOBACK.loop = 'loop';

			AUDIOBACK.appendChild(AUDIOSOURCEBACK);
			$('sounds').appendChild(AUDIOBACK);

			CurrentGameObject_J1 = gameJ1;
		}
	};
}; 
var menuJ1 = new MenuJ1();

//MAP
var MapJ1 = function(){
	this.nodes = [];
	this.speed = 0;
	this.parentObj = null;
	this.init  = function(p){
		this.parentObj = p;

		this.speed = GAME_SPEED;

		var ip = 0;
		while(ip < PATTERNS[0].length){
			this.nodes.push(PATTERNS[0][ip]);
			++ip;
		}
	};

	this.update = function(){
		var ip = 0;
		this.render();
		while(ip < this.nodes.length){
			var p = this.nodes[ip];
			if(p.tag == 'trap')
				p.update();
			++ip;
		}
		this.move();
		
	};
	this.render  = function(){
		var ip = 0;
		while(ip < this.nodes.length){
			var node   = this.nodes[ip];
			var bounds = this.nodes[ip].bounds;
			var sprite = this.nodes[ip].sprite;

			//Si le props a une image 
			if(sprite.img){
				if((node.tag == "trap" && !node.active )){
					
				}else if(node.tag != 'layer'){
					var image = new Image();
					image.src = sprite.img;
					ctx[this.parentObj.J].drawImage(
											image, 
											sprite.bgx, 
											sprite.bgy, 
											sprite.w, 
											sprite.h, 
											bounds.x, 
											bounds.y, 
											sprite.w, 
											sprite.h);

					gameJ1.character.render();

				}
			}else if(node.display != 'none'){
				ctx[this.parentObj.J].fillStyle = bounds.c;
				ctx[this.parentObj.J].fillRect( 	
										bounds.x,  
										bounds.y,  
										bounds.w,  
										bounds.h);
			}
			++ip;
		}
	};

	this.move = function(){
		var ip = 0;
		while(ip < this.nodes.length){
				var p = this.nodes[ip];
				if(p.mvt)
				p.bounds.x -= this.speed;
			++ip;
		}
	}
};

/**
 * GAME
 **/
var GameJ1 = function(){
	this.J = '';
	this.bg1= new Image();
	this.bg2= new Image();
	this.bg1.src = 'assets/J1_bg.jpg';
	this.bg2.src = 'assets/J1_bg.jpg';
	this.bg1.x = 0; 
	this.bg2.x = 0;
	this.bg1.y = 0; 
	this.bg2.y = 0;
	this.map = null;
	this.speed = 0;

	this.timeWinner = getTime();

	this.m1= new Image();
	this.m2= new Image();
	this.m1.src = 'assets/J1_mur0.png';
	this.m2.src = 'assets/J1_mur0.png';
	this.m1.x = 0; 
	this.m2.x = 0;
	this.m1.y = 432;
	this.m2.y = 432;

	this.character = null;
	//Initialisation
	this.init = function(j){
		this.J = j;
		this.speed = GAME_SPEED;
		this.map = new MapJ1();
		this.character = new CharacterJ1();
		this.enemies = new Enemy();

		this.bg2.x = MAX_WIDTH_J1 - this.bg1.x;
		this.bg2.y = 0;

		this.map.init(this);
		this.character.init(j);
		this.enemies.init(j);

		this.m2.x = MAX_WIDTH_J1 - this.m1.x;
		this.m2.y = 432;
	};

	//Mise à jour
	this.update = function(){
		this.render();
		this.move();
		this.map.update();
		this.character.update();
		this.enemies.goToPlayer( this.character.bounds.x , this.character.bounds.y );
		/*if( this.enemies.collisionPlayer) {
			
			this.character.indexSprite = 3;
		}*/
		this.renderWall();
	};

	this.move = function() {
		this.bg1.x -= this.speed;
		this.bg2.x -= this.speed;
		if (this.bg1.x <= -MAX_WIDTH_J1) {
			this.bg1.x = this.bg2.x;
			this.bg2.x = MAX_WIDTH_J1;
		}

		this.m1.x -= this.speed;
		this.m2.x -= this.speed;
		if (this.m1.x <= -MAX_WIDTH_J1) {
			this.m1.x = this.m2.x;
			this.m2.x = MAX_WIDTH_J1;
		}
	}

	//Affichage
	this.render = function(){
		// Effacement du canvas à chaque frame
		ctx[this.J].fillStyle = "#FFF";
		ctx[this.J].drawImage(this.bg1, this.bg1.x, this.bg1.y, MAX_WIDTH_J1, MAX_HEIGHT_J1);
		ctx[this.J].drawImage(this.bg2, this.bg2.x-10, this.bg2.y, MAX_WIDTH_J1, MAX_HEIGHT_J1);
	};

	//Affichage du mur du bas
	this.renderWall = function(){
		ctx[this.J].drawImage(this.m1, this.m1.x, 432, MAX_WIDTH_J1, 96);
		ctx[this.J].drawImage(this.m2, this.m2.x, 432, MAX_WIDTH_J1, 96);
	};
	//Gestion des inputs
	this.input = function(){
		
	};
};
var gameJ1 = new GameJ1();

/**
 * CHARACTER J1
 **/
var CharacterJ1 = function() {
 	this.J = '';
 	this.spritesRes = [];
 	this.spritesImg = [{
		 	img : 'assets/Sprite_Ninja_Standing.png',	// [0] ARRET
		 	bgx : 0,
		 	bgy : 0,
		 	bgw : 1040,	// WIDTH TOTALE DU SPRITE
		 	bgh : 744,	// HEIGHT TOTALE DU SPRITE
		 	k 	: 0 	// PARAMETRE DE VITESSE DE L'ANIMATION
		},{
		 	img : 'assets/Sprite_Ninja_Run.png',		// [1] COURS
		 	bgx : 0,
		 	bgy : 0,
		 	bgw : 1040,	// WIDTH TOTALE DU SPRITE
		 	bgh : 744,	// HEIGHT TOTALE DU SPRITE
		 	k 	: 0 	// PARAMETRE DE VITESSE DE L'ANIMATION
		},{
		 	img : 'assets/Sprite_Ninja_Atk.png', 		// [2] FRAPPE
		 	bgx : 0,
		 	bgy : 0,
		 	bgw : 1040,	// WIDTH TOTALE DU SPRITE
		 	bgh : 744,	// HEIGHT TOTALE DU SPRITE
		 	k 	: 0 	// PARAMETRE DE VITESSE DE L'ANIMATION
		},{
		 	img : 'assets/Sprite_Ninja_Hit.png', 		// [3] HIT
		 	bgx : 0,
		 	bgy : 0,
		 	bgw : 1040,	// WIDTH TOTALE DU SPRITE
		 	bgh : 744,	// HEIGHT TOTALE DU SPRITE
		 	k 	: 0 	// PARAMETRE DE VITESSE DE L'ANIMATION
		}];
 	this.bounds = {
			x : 200,
		 	y : 150,
		 	w : 260,	// WIDTH DU CHARACTER
		 	h : 186		// HEIGHT DU CHARACTER
		};
 	this.parameters = {
			speed : 3.5, // VITESSE DE DEPLACEMENT DU CHARACTER
			nSpeed: 15,	 // VITESSE DE DEBUG POUR NIGHTLY
			life  : 5  // VIE DE CHARACTER
		};
 	this.indexSprite = 0;	
 	this.frappeObj = null;
 	this.effectsObj = null;
 
 	// Initialisation
	this.init = function(j) {
		this.J = j;
		this.parameters.speed = (DEBUG_NIGHTLY) ? this.parameters.nSpeed : this.parameters.speed;
		// Chargement des sprites...
		this.loadSprites();
		// Instance d'un coup d'épée
		this.frappeObj = new Frappe();
		this.frappeObj.init(j, 0); // Charge l'épée [0]
		// Instance d'un effet
		//this.effectsObj = new Effects();
		//this.effectsObj.init(j, 0);
	};

 	// Chargement des sprites
 	this.loadSprites = function() {
 		var i = 0;
 		while( i < this.spritesImg.length ) {
 			var img = new Image();
 			img.src = this.spritesImg[i].img;
 			this.spritesRes[i] = img;
 			i++;
 		}
 	};

 	// Update des coordonnées du character @ each frame
 	this.update = function() {
 		this.input(); //this.input();
		//this.render();
		this.move();
 		this.checkAlive();
 	};

 		this.move = function() {
			if (this.indexSprite == 0) {
				this.bounds.x -= gameJ1.map.speed;
			}
		}

		this.checkAlive = function() {
			var alive = true;
			if (this.bounds.x + this.bounds.w/1.8 < 0) alive = false;
			if (this.parameters.life <= 0) alive = false;

			if (!alive) {
				// Kill du son
				if( $('sounds') )
					document.body.removeChild( $('sounds') );

				CurrentGameObject_J1 = gameOver;
				CurrentGameObject_J2 = gameOver;
			}
		}

 	// Affichage à l'écran du sprite du character
 	this.render = function() {
		var img = this.spritesRes[this.indexSprite];
		var s = this.spritesImg[this.indexSprite];
		var b = this.bounds;

		ctx[this.J].drawImage( img,
			s.bgx, // position x en image source
			s.bgy, // position y en image source
			b.w, // largeur image source
			b.h, // hauteur image source
			b.x, // position X sur canvas de destination
			b.y, // position Y sur canvas de destination
			b.w, // largeur Y sur canvas de destination (possibilité de zoom)
			b.h // hauteur Y sur canvas de destination (possibilité de zoom)
		);

		if( this.frappeObj.strikeFlag ) {
			this.frappeObj.render();
		}
		//if( this.effectsObj.strikeFlag ) {
			//this.effectsObj.render();
		//}
 	};

 	// Animation uniquement du character!
	this.input = function() {
		var s = this.spritesImg[this.indexSprite];
		var b = this.bounds;
		var p = this.parameters;

		var move = false;

		var vx = 0;
		var vy = 0;

		if( getKey('top').state && !this.frappeObj.strikeFlag && this.indexSprite != 3 ) {
			vy -= p.speed;
			s.bgy = b.h * 0;	// [0] : Ligne n°1 de l'image
			move = true;
			//this.effectsObj.lineFX = 0; // Effet de frappe vers le haut (pas encore prêt)
		}
		else if( getKey('bottom').state && !this.frappeObj.strikeFlag && this.indexSprite != 3 ) {
			vy += p.speed;
			s.bgy = b.h * 2;	// [2] : Ligne n°3 de l'image
			move = true;
			//this.effectsObj.lineFX = 2; // Effet de frappe vers le bas
		}
		if( getKey('right').state && !this.frappeObj.strikeFlag && this.indexSprite != 3 ) {
			vx += p.speed;
			s.bgy = b.h * 1;	// [1] : Ligne n°2 de l'image
			move = true;
			//this.effectsObj.lineFX = 1; // Effet de frappe vers la droite
		}
		else if( getKey('left').state && !this.frappeObj.strikeFlag && this.indexSprite != 3 ) {
			vx -= p.speed;
			s.bgy = b.h * 3;	// [3] : Ligne n°3 de l'image
			move = true;
			//this.effectsObj.lineFX = 3; // Effet de frappe vers la gauche (pas encore prêt)
		}
		if( getKey('top').state || getKey('right').state || getKey('bottom').state || getKey('left').state && !this.frappeObj.strikeFlag && this.indexSprite != 3 )
			s.k++;

		//log(this.indexSprite);
		if(!move) {
			s.bgx = b.w;
			if( this.indexSprite < 2 ) 
				this.indexSprite = 0; // Personnage en arrêt => sprite Standing [0]
		} else {
			if( this.indexSprite < 2)
				this.indexSprite = 1; // Personnage en mouvement => sprite Running [1]
			if(collideProps(this, vx, vy)){
				b.x += vx;
				b.y += vy;
			}
		}
		this.frappeObj.setCharactersCoords( this.bounds.x , this.bounds.y, this.spritesImg[this.indexSprite].bgy );
		//this.effectsObj.setCharactersCoords( this.bounds.x , this.bounds.y, this.spritesImg[this.indexSprite].bgy );

		// Coup d'épée demandé ?
		if( getKey('j').state && !this.frappeObj.strikeFlag ) {
		 	//s.k = 0;
		 	//this.frappeObj.strikeFlag = true;
		 	//this.effectsObj.strikeFlag = true;
		 	
		 	
		 	this.indexSprite = 2; // [2] PRESQUE PRET...
		} else if ( !this.frappeObj.strikeFlag && this.indexSprite == 2 ) {
			//s.k = 0;
			this.indexSprite = 1;
		}

		if( s.k >= 8 ) {
			s.k = 0;
			s.bgx += b.w; // On bouge le canvas du character sur l'horizontale |>>|>>|>>|
			if (s.bgx >= s.bgw) { // Si on arrive au bout de l'image, on remet à 0 la position d'affichage du background
				s.bgx = 0;
			}
		}
		
		if( this.frappeObj.strikeFlag ) {
			this.frappeObj.animate();
		}
		//if( this.effectsObj.strikeFlag ) {
		//	this.effectsObj.animate();
		//}
	};
};

/**
 * GESTION DES FRAPPES D'EPEE(S)
 **/
var Frappe = function() {
	this.J = '';
	this.FrappesRes = [];
	this.FrappesImg = [{
		 	img : 'assets/Sprite_Ninja_Epee.png',		// [0] : Epée
		 	bgx : 0,
		 	bgy : 0,
		 	bgw : 2080,	// WIDTH TOTALE DU SPRITE n°1
		 	bgh : 744,	// HEIGHT TOTALE DU SPRITE n°2
		 	k 	: 0 	// PARAMETRE DE VITESSE DE L'ANIMATION SUR CE SPRITE
		}];
	this.bounds = {
		 	w : 260,	// WIDTH DE L'EPEE
		 	h : 186		// HEIGHT DE L'EPEE
		};
	this.parameters = {
		xChr : null,
		yChr : null
	};
	this.indexFrappe = 0;
	this.strikeFlag = false; // true|false en fonction de si on a demandé une autorisation de frapper

	// Le paramètre index permet de choisir l'épée (0, 2, 3, ...)
	this.init = function(j, index) {
		this.J = j;
		this.indexFrappe = index;
		this.loadSprites();
	};

	// Chargement des sprites
 	this.loadSprites = function() {
 		// 
 		var i = 0;
 		while( i < this.FrappesImg.length ) {
 			var img = new Image();
 			img.src = this.FrappesImg[i].img;
 			this.FrappesRes[i] = img;
 			i++;
 		}
 	};

 	// Permet de récupérer les coordonnées X et Y du Character qui appelle ce strike
	this.setCharactersCoords = function(x, y, bgy) {
		this.parameters.xChr = x;
		this.parameters.yChr = y;
		this.parameters.bgyChr = bgy;
	};

 	// Fonction qui lance une frappe de l'épée
 	/*this.strike = function() {
 		// Si l'on a activé le flag "frapper".. let's go!
 		if( this.strikeFlag ) {
			this.animate();
			this.render();
		}
	};*/

	// Animation
	this.animate = function() {
		var s = this.FrappesImg[this.indexFrappe];
		var b = this.bounds;
		var p = this.parameters;

		s.k++;

		if( s.k >= 4 ) { // On ralenti le mouvement toutes les 4 frames
			s.k = 0;
			s.bgx += b.w; // On bouge le canvas de l'arme sur l'horizontale |>>|>>|>>|
			if (s.bgx >= s.bgw) { // Si on arrive au bout de l'image, on remet à 0 la position d'affichage du background
				s.bgx = 0;
				this.strikeFlag = false;
			}
		}
	};

	// Affichage de l'image
	this.render = function() {
		//  :
		var img = this.FrappesRes[this.indexFrappe];
		var s = this.FrappesImg[this.indexFrappe];
		var b = this.bounds;

		//log('render here');

		ctx[this.J].drawImage( img,
			s.bgx, // position x en image source
			this.parameters.bgyChr, //s.bgy, // position y en image source
			b.w, // largeur image source
			b.h, // hauteur image source
			this.parameters.xChr, //b.x, // position X sur canvas de destination
			this.parameters.yChr, //b.y, // position Y sur canvas de destination
			b.w, // largeur Y sur canvas de destination (possibilité de zoom)
			b.h // hauteur Y sur canvas de destination (possibilité de zoom)
		);
	};
};







function collideProps(obj, vx, vy){
	var b = obj.bounds;
	var p = obj.parameters;
	var direction = '';
	var result = true;

	var ip = 0;

	//Collision les bords
	if( b.x + vx <= -100 || 
		b.x + vx + b.w >= MAX_WIDTH_J1 + 100 ||	
		b.y + vy <= b.h/4 || 
		b.y + vy + b.h >= MAX_HEIGHT_J1 + b.h/2) {
		return false;
	}

	if (vy < 0) direction = 'up';
	else if (vy > 0) direction ='down';
	else if (vx < 0) direction = 'left';
	else if (vx > 0) direction = 'right';

	var coefX = 0;

	while(ip < gameJ1.map.nodes.length){
		var prop = gameJ1.map.nodes[ip];
		
			if(prop.tag == 'block' || prop.tag == 'trap'){
				if(direction == "up" || direction == "down")
					coefX = b.	w/4*2;
				else if(direction == "left" || direction == "right")
					coefX = b.w/3*2;
					 
				if((b.x + coefX + vx) > prop.bounds.x &&
				   (b.x + b.w/2 + vx) < prop.bounds.x + prop.bounds.w &&
				   (b.y + b.h/2 + vy) > prop.bounds.y &&
				   (b.y + b.h/2 + vy) < prop.bounds.y + prop.bounds.h)
				{
					if(prop.tag == 'trap'){
						
						prop.collide();
					}else{
						result = false;
					}
				}
			}

		++ip;
	}
	
	return result;
}